#!/usr/bin/perl

# syshogs
# Originally "pigs" from COMP 150PPP: Perl Programming Practicum (taught by Professor Alva Couch)
# Tufts University Department of Computer Science
# Written by Ming Chow
# Last updated on September 11, 2006

use Syshogs;
use strict;
#use DBI;

sub LOG_DEPENDENCIES {'LOG_DEPENDENCIES'} 
my $db_username = 'syshogs';
my $db_passwd = 'syshogs';
my $db_host = 'localhost';
my $db_name = 'syshogs';
my $option = shift;
my $loop = shift; # number of seconds to refresh snapshot
my $procs;
my $organized;
my $summary;

# If $loop contains, or is garbage, set it to 0
if ($loop !~ /^[0-9]+$/) {
	$loop = 0;
}

if ($option eq '-li')
{
	while (1)
	{
		$procs = undef; # Make brand new snapshot of procs with no previous information
		&main();
		&log_to_database();
		sleep($loop);
	}
}
elsif ($option eq '-ld')
{
	&main();
	&log_to_database(&LOG_DEPENDENCIES);
}
elsif ($option eq '-c')
{
	while (1)
	{
		&main();
		sleep($loop);
	}
}
elsif ($option eq '-i')
{
	while (1)
	{
		$procs = undef; # Make brand new snapshot of procs with no previous information
		&main();
		sleep($loop);
	}
}
elsif ($option eq undef) {
 	&main();
}
elsif ($option eq '-h') {
	&help();
}
else {
	print STDERR "Invalid option!\nsyshogs usage: 'syshogs <option>'\n";
	&help();
}

sub help
{
	print "options:\n";
	print "  -i <n>: a fresh new snapshot after every 'n' seconds (n is 0 if n is garbage)\n";
	print "  -c <n>: a cumulative snapshot after every 'n' seconds\n";
	print "  -li <n>: a fresh new snapshot after every 'n' seconds, and log information on all the processes into database\n";
	print "  -ld: a single snapshot and log information on all the processes and *dependencies* into database\n";
	print "  -h: displays this very list that you are looking at :-)\n";
}

sub log_to_database
{
	my $log_dependencies = shift;
	my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime time;
	$year += 1900;
	$mon++;
	$mon = "0$mon" if ($mon < 10);
	$mday = "0$mday" if ($mday < 10);
	$hour = "0$hour" if ($hour < 10);
	$min = "0$min" if ($min < 10);
	$sec = "0$sec" if ($sec < 10);
	my $timestamp = "$year-$mon-$mday $hour:$min:$sec";
	my $dsn = "DBI:mysql:$db_name:$db_host";
	my $dbh = DBI->connect($dsn, $db_username, $db_passwd) or die "Cannot connect to database: " . $DBI::errstr;
	if ($dbh != undef)
	{
		my $sql_statement;
		my $sth;

		# Insert the processes into database
		foreach my $uid (keys %{$organized})
		{
			foreach my $element (@{$organized->{$uid}})
			{
				if ($element->{'VmSize'} == undef) {
					$element->{'VmSize'} = 0;
				}
				if ($element->{'jiffies'} == undef) {
					$element->{'jiffies'} = 0;
				}
				$sql_statement = "insert into processes (uid, pid, pname, vmsize, jiffies, added_on) values ($uid, $element->{'pid'}, '$element->{'pname'}', $element->{'VmSize'}, $element->{'jiffies'}, '$timestamp')";
				$sth = $dbh->prepare($sql_statement);
				$sth->execute() or die "Cannot execute SQL query: " . $sth->errstr();
				$sth->finish;
				if ($element->{'dependencies'} ne undef && $log_dependencies eq &LOG_DEPENDENCIES)
				{
					
					# Insert all the dependencies for each process into database
					foreach my $pathname (keys %{$element->{'dependencies'}})
					{
						$sql_statement = "insert into dependencies (uid, pid, pathname, added_on) values ($uid, $element->{'pid'}, '$pathname', '$timestamp')";
						$sth = $dbh->prepare($sql_statement);
						$sth->execute() or die "Cannot execute SQL query: " . $sth->errstr();
						$sth->finish;
					}
				}
			}
		}
		$sth->finish;
		$dbh->disconnect or warn ("Database disconnect failed: $!");
	}
}

sub main
{
	$procs = &Syshogs::accumulate($procs);
	if ($procs != undef)
	{
		$organized = &Syshogs::organize_by_user($procs);
		$summary = &Syshogs::summary($organized);
		print `/usr/bin/clear`; # Clear screen
		&Syshogs::render($summary);
	}
	else {
		print STDERR "No information available.  Perhaps you should run syshogs as root, or your operating system does not support the proc file system.\n";
	}
}
